﻿/******************************************************************************
 * 
 * Announce: CSharpKit, Basic algorithms, components and definitions.
 *           Copyright (C) ShenYongchen.
 *           All rights reserved.
 *   Author: 申永辰.郑州 (shenyczz@163.com)
 *  WebSite: http://github.com/shenyczz/CSharpKit
 *
 * THIS CODE IS LICENSED UNDER THE MIT LICENSE (MIT).
 * THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 
 * ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
 * IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
 * PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
 * 
******************************************************************************/

using System;
using System.Collections.Generic;

namespace CSharpKit.Numerics.LinearAlgebra
{
    /// <summary>
    /// 构造器实例
    /// </summary>
    /// <typeparam name="T"></typeparam>
    internal static class BuilderInstance<T>
        where T : struct, IFormattable, IEquatable<T>
    {
        static Lazy<List<Numeric<T>>> _singleton = new Lazy<List<Numeric<T>>>(Create);
        static List<Numeric<T>> Create()
        {
            if (typeof(T) == typeof(double))
            {
                return new List<Numeric<T>>()
                {
                    (MatrixBuilder<T>)(object)new MatrixBuilderDouble(),
                    (VectorBuilder<T>)(object)new VectorBuilderDouble(),
                };
            }

            throw new NotSupportedException(string.Format("Matrices and vectors of type '{0}' are not supported. Only Double, Single, Complex or Complex32 are supported at this point.", typeof(T).Name));
        }

        public static MatrixBuilder<T> MatrixBuilder
        {
            get => _singleton.Value.Find(p => p is MatrixBuilder<T>) as MatrixBuilder<T>;
        }

        public static VectorBuilder<T> VectorBuilder
        {
            get => _singleton.Value.Find(p => p is VectorBuilder<T>) as VectorBuilder<T>;
        }




        /*
        static Lazy<Tuple<MatrixBuilder<T>, VectorBuilder<T>>>
        _singleton = new Lazy<Tuple<MatrixBuilder<T>, VectorBuilder<T>>>(Create);

        static Tuple<MatrixBuilder<T>, VectorBuilder<T>> Create()
        {
            if (typeof(T) == typeof(System.Numerics.Complex))
            {
                return new Tuple<MatrixBuilder<T>, VectorBuilder<T>>(
                    (MatrixBuilder<T>)(object)new LinearAlgebra.Complex.MatrixBuilder(),
                    (VectorBuilder<T>)(object)new LinearAlgebra.Complex.VectorBuilder());
            }

            if (typeof(T) == typeof(Numerics.Complex32))
            {
                return new Tuple<MatrixBuilder<T>, VectorBuilder<T>>(
                    (MatrixBuilder<T>)(object)new Complex32.MatrixBuilder(),
                    (VectorBuilder<T>)(object)new Complex32.VectorBuilder());
            }

            if (typeof(T) == typeof(double))
            {
                return new Tuple<MatrixBuilder<T>, VectorBuilder<T>>(
                    (MatrixBuilder<T>)(object)new Double.MatrixBuilder(),
                    (VectorBuilder<T>)(object)new Double.VectorBuilder());
            }

            if (typeof(T) == typeof(float))
            {
                return new Tuple<MatrixBuilder<T>, VectorBuilder<T>>(
                    (MatrixBuilder<T>)(object)new Single.MatrixBuilder(),
                    (VectorBuilder<T>)(object)new Single.VectorBuilder());
            }

            throw new NotSupportedException(string.Format("Matrices and vectors of type '{0}' are not supported. Only Double, Single, Complex or Complex32 are supported at this point.", typeof(T).Name));
        }

        public static void Register(MatrixBuilder<T> matrixBuilder, VectorBuilder<T> vectorBuilder)
        {
            _singleton = new Lazy<Tuple<MatrixBuilder<T>, VectorBuilder<T>>>(() => new Tuple<MatrixBuilder<T>, VectorBuilder<T>>(matrixBuilder, vectorBuilder));
        }


        public static VectorBuilder<T> Vector
        {
            get { return _singleton.Value.Item2; }
        }
        */
    }


}
